﻿using System;
using FunctionalCLR.Core;
using Zove.Runtime;
using Zove.Shell;
using FunctionalCLR.Shell;

namespace Zove.Shell.Modelling
{
    public class FormulateNode : ContextFuncNode {

        public FormulateNode()
            : base() {
            base.Value = "formulate";
        }

        public IZoveShellContext ZoveShellContext
        {
            get
            {
                return base.Context as IZoveShellContext;
            }
        }

        public override object Evaluate() {
            if (Parameters.Count < 1)
            {
                throw new ArgumentException(
                    "usage: formulate(factor)");
            }

            RuntimeFactor factor 
                = ZoveShellContext.GetFactor(
                Parameters[0].Value);
            if (factor.Status == RuntimeFactorStatus.Unknown) {
                throw new Exception(
                    string.Format(
                    "Cannot form a solution for factor '{0}' due to its unknown status.", factor.Name));
            }

            string instanceName = factor.ParentModel.Solution.Name;
            SolutionSimplifier ss = new SolutionSimplifier(factor);
            string result = ss.Parse();
            result = Utils.Prefixize(instanceName, result,
                ZoveDependencyManager.Instance.FunctionManager);

            Parser parser
                = DefaultDependencyManager.Instance.ParserFactory.CreateParser(
                result);
            Node root = parser.Parse();

            return root;
        }

        public override string ToString() {
            return this.Evaluate().ToString();
        }
    }
}
